#define _UART_C_
/* Includes ---------------------------------------------------------*/
/* USER CODE BEGIN Includes */
//#include "fm33lg0xx.h"
#include "usart.h"
/* USER CODE END Includes */

/* Types ------------------------------------------------------------*/
/* USER CODE BEGIN Types */

/* USER CODE END Types */

/* Constants --------------------------------------------------------*/
/* USER CODE BEGIN Constants */

/* USER CODE END Constants */

/* Macro ------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
#define CMD_CODE_SWITCH_HART_CHL                                   (0x01)
#define CMD_CODE_SWITCH_METER_CHL                                  (0x02)
#define CMD_CODE_SWITCH_RGB                                        (0x03)
#define CMD_CODE_SWITCH_ELEC_SALVE                                 (0x04)
/* USER CODE END Macro */

/* Variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
STUartData stUart0Rx;
uint8_t gucUsartFlags = 0;
uint8_t gucUsartRxTimerCnt = 0;
/* USER CODE END Variables */

/* Function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FP */
static void vUART0GPIOInit(void);
static void vUART0InterruptInit(void);
static void vUART0NVICInit(void);
void vUART0Send(uint8_t *pdata, uint8_t ucSize);
void vClearRxMessageBuffer(void);
/* USER CODE END FP */

/**
  * @brief  @
  * @param  @
  * @retval @
  */
void vUART0MsgHandler(void)
{
	if(GET_USART_RX_FINISHED_FLG())
	{
		if((stUart0Rx.ucAryBuffer[0] == 0xAA) && (stUart0Rx.ucAryBuffer[1] == 0x55) && 
		   (stUart0Rx.ucAryBuffer[stUart0Rx.ucSize - 2] == 0x0D) && (stUart0Rx.ucAryBuffer[stUart0Rx.ucSize - 1] == 0x0A))
		{
			uint8_t ucCMDCode = stUart0Rx.ucAryBuffer[2];
			uint8_t ucSize = stUart0Rx.ucAryBuffer[3];
			uint8_t ucDevices = stUart0Rx.ucAryBuffer[4];
			uint8_t ucCheckSum = 0xAA + 0x55 + ucCMDCode + ucSize + ucDevices;
			bool bSwitchOK = false;
			uint8_t ucArrayResponseMsg[16] = {0x00};
			uint8_t ucMsgSize = 0;
			
			// response message
			// header
			ucArrayResponseMsg[0] = 0xAA;
			ucArrayResponseMsg[1] = 0x55;
			// command
			ucArrayResponseMsg[2] = stUart0Rx.ucAryBuffer[2];
			// size
			ucArrayResponseMsg[3] = 2;
			// result
			//ucArrayResponseMsg[4] = 0x00; // success
			//ucArrayResponseMsg[4] = 0xff; // fail
			// device
			ucArrayResponseMsg[5] = stUart0Rx.ucAryBuffer[4];
			
			if(((ucCMDCode != CMD_CODE_SWITCH_HART_CHL) && (ucCMDCode != CMD_CODE_SWITCH_METER_CHL) && (ucCMDCode != CMD_CODE_SWITCH_RGB) && \
				(ucCMDCode != CMD_CODE_SWITCH_ELEC_SALVE)) || \
				(ucCheckSum != stUart0Rx.ucAryBuffer[5]))
			{
				ucArrayResponseMsg[4] = 0xff;
				
				// checksum
				ucArrayResponseMsg[6] = ucArrayResponseMsg[0] + ucArrayResponseMsg[1] + ucArrayResponseMsg[2] + ucArrayResponseMsg[3] + \
										ucArrayResponseMsg[4] + ucArrayResponseMsg[5];
				// tail
				ucArrayResponseMsg[7] = 0x0D;
				ucArrayResponseMsg[8] = 0x0A;
				
				ucMsgSize = 9;
				
				vUART0Send(ucArrayResponseMsg, ucMsgSize);
				
				vClearRxMessageBuffer();
				
				return;
			}
		
			switch(ucCMDCode)
			{
				case CMD_CODE_SWITCH_HART_CHL:
				case CMD_CODE_SWITCH_METER_CHL:
					for(uint8_t i = 0; i < 32; i++)
					{
						if(ucCMDCode == CMD_CODE_SWITCH_HART_CHL)
						{
							if(bSwitchOK == false)
							{
								if(ucDevices == (i + 1))
								{
									vRelaySwitchWithHARTOrMeter(gEnumArryChlID[i], eHART, _ON);
									bSwitchOK = true;
								}
								else
								{
									vRelaySwitchWithHARTOrMeter(gEnumArryChlID[i], eHART, _OFF);
								}
							}
							else
							{
								vRelaySwitchWithHARTOrMeter(gEnumArryChlID[i], eHART, _OFF);
							}
						}
						else if(ucCMDCode == CMD_CODE_SWITCH_METER_CHL)
						{
							if(ucDevices == (i + 1))
							{
								vRelaySwitchWithHARTOrMeter(gEnumArryChlID[i], eMeter, _ON);
							}
							else
							{
								vRelaySwitchWithHARTOrMeter(gEnumArryChlID[i], eMeter, _OFF);
							}
						}
						else
						{
							break;
						}
					}
					break;
					
				case CMD_CODE_SWITCH_RGB:
					switch(stUart0Rx.ucAryBuffer[4])
					{
						case 0x11:
							vSetAlarmROnOrOff(true);
							vSetAlarmGOnOrOff(false);
						
							CLR_R_Flashing();
							CLR_G_Flashing();
							break;
						case 0x22:
							vSetAlarmROnOrOff(false);
							vSetAlarmGOnOrOff(true);
						
							CLR_R_Flashing();
							CLR_G_Flashing();
							break;
						case 0x44:
							vSetAlarmBOnOrOff(true);
						
							CLR_B_Flashing();
							break;
						case 0x01:
							vSetAlarmROnOrOff(false);
							
							CLR_R_Flashing();
							break;
						case 0x02:
							vSetAlarmGOnOrOff(false);
						
							CLR_G_Flashing();
							break;
						case 0x04:
							vSetAlarmBOnOrOff(false);
						
							CLR_B_Flashing();
							break;
						case 0x81:
							vSetAlarmGOnOrOff(false);
						
							SET_R_Flashing();
							CLR_G_Flashing();
							break;
						case 0x82:
							vSetAlarmROnOrOff(false);
						
							CLR_R_Flashing();
							SET_G_Flashing();
							break;
						case 0x84:
//							vSetAlarmROnOrOff(false);
//							vSetAlarmGOnOrOff(false);
//						
//							CLR_R_Flashing();
//							CLR_G_Flashing();
//							SET_B_Flashing();
							break;
						default:
							vSetAlarmROnOrOff(false);
							vSetAlarmROnOrOff(false);
							vSetAlarmROnOrOff(false);
						
							CLR_R_Flashing();
							CLR_G_Flashing();
							CLR_B_Flashing();
							break;
					}
					break;
					
				case CMD_CODE_SWITCH_ELEC_SALVE:
					if(stUart0Rx.ucAryBuffer[4] == 0x01)
					{
						FL_GPIO_SetOutputPin(GPIOC, FL_GPIO_PIN_12);
						FL_GPIO_ResetOutputPin(GPIOC, FL_GPIO_PIN_5);
					}
					else if(stUart0Rx.ucAryBuffer[4] == 0x00)
					{
						FL_GPIO_ResetOutputPin(GPIOC, FL_GPIO_PIN_12);
					}
					else if(stUart0Rx.ucAryBuffer[4] == 0x03)
					{
						FL_GPIO_SetOutputPin(GPIOC, FL_GPIO_PIN_5);
						FL_GPIO_ResetOutputPin(GPIOC, FL_GPIO_PIN_12);
					}
					else if(stUart0Rx.ucAryBuffer[4] == 0x02)
					{
						FL_GPIO_ResetOutputPin(GPIOC, FL_GPIO_PIN_5);
					}
					else
					{
						FL_GPIO_ResetOutputPin(GPIOC, FL_GPIO_PIN_12);
						FL_GPIO_ResetOutputPin(GPIOC, FL_GPIO_PIN_5);
					}
					break;
				
				
				default:
					break;
			}

			
			ucArrayResponseMsg[4] = 0x00;
			
			// checksum
			ucArrayResponseMsg[6] = ucArrayResponseMsg[0] + ucArrayResponseMsg[1] + ucArrayResponseMsg[2] + ucArrayResponseMsg[3] + \
									ucArrayResponseMsg[4] + ucArrayResponseMsg[5];
			// tail
			ucArrayResponseMsg[7] = 0x0D;
			ucArrayResponseMsg[8] = 0x0A;
			
			ucMsgSize = 9;
				
			vUART0Send(ucArrayResponseMsg, ucMsgSize);
		}
		
		vClearRxMessageBuffer();
	}
}
/**
  * @brief  @
  * @param  @
  * @retval @
  */
void vClearRxMessageBuffer(void)
{
	CLR_USART_RX_FINISHED_FLG();
	stUart0Rx.ucSize = 0;
	memset((uint8_t *)stUart0Rx.ucAryBuffer, 0x00, USART_RX_BUFFER_SIZE);
}
/**
  * @brief   Debug UART Interrupt Initialization function
  * @param  void
  * @retval None
  */
void vUART0Init(void)
{
	vUART0GPIOInit();
	vUART0InterruptInit();
	vUART0NVICInit();
}
/**
  * @brief   Debug UART GPIO Initialization function
  * @param  void
  * @retval None
  */
static void vUART0GPIOInit(void)
{
    FL_GPIO_InitTypeDef GPIO_InitStruct;

    FL_UART_InitTypeDef UART0_InitStruct;

    GPIO_InitStruct.pin = FL_GPIO_PIN_13;
    GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
    GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.pull = FL_ENABLE;
    GPIO_InitStruct.remapPin = FL_DISABLE;
    GPIO_InitStruct.analogSwitch = FL_DISABLE;
    FL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.pin = FL_GPIO_PIN_14;
    GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
    GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.pull = FL_DISABLE;
    GPIO_InitStruct.remapPin = FL_DISABLE;
    GPIO_InitStruct.analogSwitch = FL_DISABLE;
    FL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    UART0_InitStruct.clockSrc = FL_CMU_UART0_CLK_SOURCE_APBCLK;
    UART0_InitStruct.baudRate = 19200;
    UART0_InitStruct.transferDirection = FL_UART_DIRECTION_TX_RX;
    UART0_InitStruct.dataWidth = FL_UART_DATA_WIDTH_8B;
    UART0_InitStruct.stopBits = FL_UART_STOP_BIT_WIDTH_1B;
    UART0_InitStruct.parity = FL_UART_PARITY_NONE;

    FL_UART_Init(UART0, &UART0_InitStruct);
}
/**
  * @brief   Debug UART Interrupt Initialization function
  * @param  void
  * @retval None
  */
static void vUART0InterruptInit(void)
{
	FL_UART_ClearFlag_RXBuffFull(UART0);
    FL_UART_EnableIT_RXBuffFull(UART0);
}
/**
  * @brief   Debug UART Interrupt Initialization function
  * @param  void
  * @retval None
  */
static void vUART0NVICInit(void)
{
	FL_NVIC_ConfigTypeDef InterruptConfigStruct;

    InterruptConfigStruct.preemptPriority = 0x02;
    FL_NVIC_Init(&InterruptConfigStruct, UART0_IRQn);
}
/**
  * @brief   Debug UART Interrupt function
  * @param  void
  * @retval None
  */
void UART0_IRQHandler(void)
{
    uint32_t ulUartRxBuffFullIT = 0;
    uint32_t ulUartRxBuffFullFlg = 0;

    ulUartRxBuffFullIT = FL_UART_IsEnabledIT_RXBuffFull(UART0);
    ulUartRxBuffFullFlg = FL_UART_IsActiveFlag_RXBuffFull(UART0);

    if((ulUartRxBuffFullIT == 0x01UL) && (ulUartRxBuffFullFlg == 0x01UL))
    {
		if(GET_USART_RX_START_FLG())
		{
			stUart0Rx.ucAryBuffer[stUart0Rx.ucSize++] = FL_UART_ReadRXBuff(UART0);
			gucUsartRxTimerCnt = 0;
			
			if((stUart0Rx.ucAryBuffer[stUart0Rx.ucSize - 1] == 0x0A) && (stUart0Rx.ucAryBuffer[stUart0Rx.ucSize - 2] == 0x0D))
			{
				SET_USART_RX_FINISHED_FLG();			
				CLR_USART_RX_START_FLG();
			}
		}
		else
		{
			SET_USART_RX_START_FLG();
		}
    }
}
/**
  * @brief  @
  * @param  @
  * @retval @
  */
void vUART0Send(uint8_t *pdata, uint8_t ucSize)
{
	uint8_t i = 0;
	
	for(i = 0; i < ucSize; i++)
	{
		FL_UART_WriteTXBuff(UART0, (uint8_t)pdata[i]);
		while(FL_UART_IsActiveFlag_TXBuffEmpty(UART0) != FL_SET);
    }
}
/**
  * @brief  fputc, enable printf
  * @param  void
  * @retval None
  */
int fputc(int ch, FILE *f)
{
    FL_UART_WriteTXBuff(UART0, (uint8_t)ch);
    while(FL_UART_IsActiveFlag_TXBuffEmpty(UART0) != FL_SET);
    return ch;
}
